perm filename PAPERX.TEX[UHF,DEK] blob sn#841766 filedate 1987-06-19 generic text, type C, neo UTF8
COMMENT āŠ—   VALID 00003 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	% Fonts for Digital Halftones, to be submitted to TUGboat: Addendum
C00005 00003	\pageno=25
C00013 ENDMK
CāŠ—;
% Fonts for Digital Halftones, to be submitted to TUGboat: Addendum
% (this version assumes that \hsize=6.5in!)

\font\logo=manfnt \def\MF{{\logo META}\-{\logo FONT}}

\newif\ifaps % are we making copy for the APS?
%\apsfalse
\apstrue

\newcount\n
\def\tbox#1{\hidewidth\vbox to1.5em{\offinterlineskip\tilt
 \vfil\expandafter\tb\number#1\empty\tb\vfil}\hidewidth}
\def\tb#1#2\tb{\ifx#1\empty\else\tb#2\tb\hbox{#1}\fi}

\def\mbox#1{$\vcenter{\kern-.2pt\hrule\kern-.2pt
 \hbox to12pt{\kern-.2pt\vrule height 9pt depth 3pt\hss#1\hss\vrule\kern-.2pt}
 \kern-.2pt\hrule\kern-.2pt}$}
\def\bbox{$\vcenter{\hbox to12pt{\vrule height 9pt width0pt depth 3pt\hss}
 \kern-.2pt\hrule\kern-.2pt}$}
\def\lbox{$\vcenter{\hbox to12pt{\kern-.2pt\vrule height 9pt depth 3pt\hss}}$}

\chardef\other=12
\def\ttverbatim{\begingroup
  \catcode`\\=\other \catcode`\{=\other \catcode`\}=\other
  \catcode`\$=\other \catcode`\&=\other \catcode`\#=\other
  \catcode`\%=\other \catcode`\~=\other \catcode`\↑=\other
  \catcode`\_=\other
  \obeyspaces \obeylines \tt}
{\obeyspaces\gdef {\ }}
\catcode`\|=\active \def|{\ttverbatim\let|=\endgroup}
\def\beginlines{\par\begingroup\nobreak\medskip\parindent=0pt \obeylines
  \hrule\kern1pt\nobreak \everypar{\strut}}
\def\endlines{\kern1pt\hrule\endgroup\medbreak\noindent}

\pageno=25
\noindent\strut{\bf Addendum}
\vskip 1pt plus 1pt
\noindent Stop the presses! When I wrote the preceding pages (and had
them typeset), I was unaware of a ``well known'' method that should have
been included for comparison. So far this paper has considered
%\leftline{\bf Fonts for Digital Halftones: Addendum}
%\medskip
%\leftline{\indent Donald E. Knuth}
%\leftline{\indent Stanford University}
%\bigskip
%\noindent
%When I wrote the paper that appeared in {\sl TUGboat\/ \bf8}, 2 (July, 1987),
%999--999, I was unaware of an important method that should have been included
%for comparison. My paper considered
(1)~a halftone font with 65 levels of gray, in which each $8\times8$ character 
essentially contributes two dots to a picture; and
(2)~a halftone font with 33 levels of gray, in which each $4\times8$ character
contributes one dot to a picture. It's also possible to construct (3)~a halftone
font with 17 levels of gray, in which each $4\times4$ character essentially
contributes half of a dot (actually two quarter-dots) to a picture. This
third method is based on an idea due to Robert L. Gard [{\sl Computer Graphics
and Image Processing\/ \bf5} (1976), 151--171].

The $k$th level of gray in the half-dot
scheme is obtained by blackening cells 0 to~$k-1$ in the array
$$\vcenter{\halign{&\mbox{#}\cr
1&5&10&14\cr
3&7&8&12\cr
13&9&6&2\cr
15&11&4&0\cr}}
\qquad \rm or \qquad
\vcenter{\halign{&\mbox{#}\cr
14&10&5&1\cr
12&8&7&3\cr
2&6&9&13\cr
0&4&11&15\cr}}\,\,.$$
(We actually make two sets of characters, one the mirror image of the other,
and alternate between them as a picture is typeset.)
The following \MF\ file will generate such a font |hd300|, in essentially the
%same way that the other fonts |dot300| and |hf300| were generated in my paper:
same way that the other fonts |dot300| and |hf300| were generated earlier:
\beginlines
|% halftone font with 17 levels of gray, characters "A" (white) to "Q" (black)|
|% includes also the mirror-reflected characters "a" (white) to "q" (black)|
\smallskip
|pair p[]; % the pixels in order (first p0 becomes black, then p1, etc.)|
|p0=(3,0); p4=(2,0); p8=(2,2); p12=(3,2);|
|transform r; r=identity rotatedaround ((1.5,1.5),180);|
\smallbreak
|for i=0 step 4 until 12: p[i+1]=p[i] transformed r;|
| p[i+2]=p[i] shifted (0,1); p[i+3]=p[i+2] transformed r; endfor|
\smallbreak
|w#:=4/pt; % that's 4 pixels|
|font_quad:=w#; designsize:=8w#;|
\smallbreak
|r:=identity reflectedabout ((2,0),(2,3));|
|picture prevchar; prevchar=nullpicture; % the pixels blackened so far|
|for i=0 upto 16:|
| beginchar(i+ASCII"A",w#,w#,0); currentpicture:=prevchar;|
| if i>0: addto currentpicture also unitpixel shifted p[i-1]; fi|
| prevchar:=currentpicture; endchar;|
| beginchar(i+ASCII"a",w#,w#,0);|
| currentpicture:=prevchar transformed r; endchar;|
| endfor|
\endlines

Here are four pictures for comparison, showing also the result of the elaborate
``dot diffusion'' method discussed at the end of my paper:
$$\vbox{\vbox to 44mm{}
\def\qbox#1{\hbox to.25\hsize{\hfil#1\hfil}}
\hbox{\qbox{double dot}\qbox{single dot}\qbox{half dot}\qbox{dot diffusion}}}$$
(Each of these was printed on a Canon laser printer with 300 pixels per inch.)
Gard's half-dot method clearly improves the quality of single-dot pictures;
it also has the advantage that its characters are square instead of diamond-shaped,
hence the data is easier to compute. On the other hand, it does require twice
as much data. Indeed, the double-dot picture shown here was typeset from
64 rows of 55 characters each; the single-dot picture was typeset from 128
rows of 55 characters each; and the half-dot picture was typeset from 128
rows of 110 characters each.

The upper left corner of the half-dot data for Mona Lisa looks like this:
\beginlines
|\beginhalftone|
|mMmMmLlLkKjJiIiIjJjJjJiIgGiJjJiGgGgIiIgGgGgGgGgIgFgGgGgGgFfFeFfFeGgGgGgGgGgFfFgIi| \dots
|LmMlLkKlLkJiIiHiIiJjJkJiGgIiIiGgFgGgGgGgGfFfGgFfEfFgFfFfGgEgGfEfGgGgGgGfFfFgGeGiH| \dots
|kKkKkKkKkJiIiHiIiIjJkKkJiIgGgFgIgFfFfFgGfEeEeEeEfGeGgGgHiJjJjIgGiGfGgGgFeFeGgFgGg| \dots
|JjJjKkKkKjIiGiIgGiJkJjJiIiIgGfGiGfEfEfGfFeEdEeDdEeFiKlMnNnNnNnMlKiGfFfFfFeFfFeFgG| \dots
|jJkJkKkLkJiHgGgGgIiJjJjIgGgFeFeGgGfEeEfEeDdDdEdDeJlNnOnOoOoOoOmOoNmKgEeDeEeEeDeEf| \dots
\endlines
Uppercase and lowercase letters alternate in a checkerboard fashion, so that
the reflected characters will appear in the correct positions. The |\beginhalftone|
macro is the same for half dots as for double dots; only the font name and the
data encoding scheme are different.

\bye